#pragma once


#include "maya/MPoint.h"
#include <map>
#include "TriangleBase.h"
#include "maya/MItMeshPolygon.h"
#include "maya/MItMeshVertex.h"
#include "Utilities.h"
#include <vector>
#include <set>
#include <queue>

using namespace std;

class SubMesh;
class VertexBase
{
public:
	struct uvPoint {
		double u;
		double v;
	};




	//Setup Functions
	VertexBase(int _vertexNumber, MPoint _position);
	VertexBase();
	~VertexBase(void);	
	void addTriangleParent(TriangleBase* parent, double angle);
	
	//Minimisation Function Calls
	double getAngularDistortionInTriangle(TriangleBase* in);
	double reconstructability();

	//Core Data getters
	MPoint getPos();
	int getNum();
	double sumAngles();	
	double getAngle(TriangleBase* in);
	double getOptimumAngle(TriangleBase* in);
	double getWeight(TriangleBase* in);
	uvPoint getUVPoint(TriangleBase* in);
	map<TriangleBase*, uvPoint> getAllUVs();

	//Core Data Setters
	void setUVPoint(double u, double v, TriangleBase* in);
	void setOptimalAngle(TriangleBase* parent);
	void setAngle(TriangleBase* in, double newAngle);

	//Boundary Vertex
	void setBoundary(bool);
	bool onBoundary();

	//Utility	
	void printAllContents();
	void printContents(TriangleBase*);

	//Distortion
	void setDistortion(double _distortion, int _radius, double _R, SubMesh* sm);
	void setDistortionToRad0();
	void setRad0Distortion(double _distortion);
	double getRad0Distortion();
	int getRadius();
	double getR();
	void setR(double _R);
	double getDistortion();	

	//Edge Related Functions
	void getConnectedEdges(vector<int>& output);
	void setConnectedEdges(MIntArray input);
	vector<TriangleBase*> getAdjacentTriangles();

	//Submesh Access Functions
	void setSubMesh(SubMesh* sm);
	SubMesh* getSubMesh();
	void cleanMemory();

	//Transformation Functions:
	bool isFixed(TriangleBase* in);
	void averageOutPositions(TriangleBase* in, TriangleBase* in2, double newU, double newV);
	
private:
	vector<VertexBase*> getAdjacentVertices();
	struct angleSet {
		double angle;
		double originalAngle;
		double optimumAngle;
		double weight;
		EdgeBase* oppositeEdge;		
	};
	int vertexNumber;

	MPoint position;	
	
	bool boundaryVertex;
	vector<int> connectedEdges;

	map<TriangleBase*, angleSet> parents;
	map<TriangleBase*, uvPoint> uvs;
	SubMesh* maxDistortionSubMesh;	
	double distortion;
	double rad0Distortion;
	int radius;
	double R;
	
};

